home *** CD-ROM | disk | FTP | other *** search
- //SHARE-IN-MEMORY=true
- // Copyright 2000, 2001, 2002, 2003 Macromedia, Inc. All rights reserved.
-
- var translatorInfo = new Array();
- var lastInStr = "";
- var lastOutStr = "";
- var lastIndex = "";
- var lastDynamicTextFormat = null;
- var g_index = "";
- var debugMegaLock = false;
- var debugTagSpan = false;
- var debugTranslationMgr = false;
-
- /////////////////////////////////////////////// TranslationManager Class //////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TranslationManager::TranslationManager
- // Purpose : Instantiate this object and call its translate method within your translators
- // translateMarkup() function. This will create a translator that utilizes the
- // translation rules defined in the XML participant files containing a
- // translator section.
- // Arguments: translatorClass - the translator class as specified by the translators
- // getTranslatorInfo() function. This name will be used as the
- // translatorClass attribute of the MM:BeginLock tags.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TranslationManager(translatorClass, serverModel, serverLanguage)
- {
- // Private Members
- this.docIsLatin1 = null;
- this.inStr = "";
- this.translatorClass = translatorClass;
- this.defaultDirectiveTag = translatorClass; // the default tag name for directives
- if (serverLanguage)
- {
- this.index = serverModel + ":" + serverLanguage;
- }
- else
- {
- this.index = serverModel;
- }
- g_index = this.index; // for the sorting function
- this.requery = false;
- this.offsetTagBegin = -1;
- this.offsetTagEnd = -1;
- this.currentTagName = null;
- this.whereToSearch = "";
- this.dynamicTextFormat = dw.getDynamicTextFormat();
- this.params = new Array();
- this.dataSources = new Array();
- this.CFOutput = new Stack(); // Cold Fusion specific to ensure dynamic data within cfoutput tags
- this.translator = new translator; // translator class which interfaces to the Translator Support Library (TSL)
- if (translatorInfo[this.index] == null)
- {
- translatorInfo[this.index] = new Array(); // repository for XML translator information
- translatorInfo[this.index].lookInAllAttributes = false;
- translatorInfo[this.index].lookInAllTags = false;
- }
-
- // Methods to use in identifying dynamic tags and attributes
- this.serverModelAlwaysCheckTag = null;
- this.serverModelAlwaysCheckAttribute = null;
-
- // Methods for constructing whole tag spans
- this.inTagSpan = false; // currently inside tag span
- this.tagSpan = null; // contents of tag span thus far
- this.tagSpanRecover = false; // on second pass through tag span
- this.tagSpanName = null; // name of tag
- this.tagSpanCounter = null; // used to match up nested tags
- this.tagSpanParts = null; // tag+name and tag+* participants
- this.tagSpanSnapshot = null;
- this.tagSpanLastIndex = -1;
-
- // Stack of tags that enclose current code (if there are any)
- this.enclosingTags = new Array();
-
- // Object with methods getTranslation and setTranslation. If non-null,
- // will be used to cache all tag spans.
- this.tagSpanCache = null;
-
- this.mode = "preview";
- this.inEditMode = false;
- this.editModeEndOffset = -1;
- this.editModeFullCode = null;
- this.editModeFullTranslation = null;
-
- // Megalocks aggregate several separate locked regions into one.
- this.inMegaLock = false;
- this.megaLockCode = null;
- this.megaLockTranslation = null;
- this.megaLockPreCodeOffset = 0;
- this.megaLockSnapshot = null;
-
- // Maintenance for reparsing (when a tag span doesn't match any of the
- // available translations or when parsing in dual-mode)
- this.reparse = false;
- this.reparseSnapshot = null;
-
- this.directives = "";
- }
- // public methods
- TranslationManager.prototype.translate = TM_translate;
- TranslationManager.prototype.notifyXMLChange = TM_notifyXMLChange;
-
- // public static methods
- TranslationManager.findTagLength = TM_findTagLength;
- TranslationManager.getAttributeValue = TM_getAttributeValue;
- TranslationManager.splitBody = TM_splitBody;
-
- // private methods
- TranslationManager.prototype.getTranslatorInfo = TM_getTranslatorInfo;
- TranslationManager.prototype.getParticipant = TM_getParticipant;
- TranslationManager.prototype.getDirective = TM_getDirective;
- TranslationManager.prototype.getAttribute = TM_getAttribute;
- TranslationManager.prototype.getText = TM_getText;
- TranslationManager.prototype.getTag = TM_getTag;
- TranslationManager.prototype.getData = TM_getData;
- TranslationManager.prototype.getTokens = TM_getTokens;
- TranslationManager.prototype.isPattern = TM_isPattern;
- TranslationManager.prototype.getCurrentTagName = TM_getCurrentTagName;
- TranslationManager.prototype.getCurrentTag = TM_getCurrentTag;
- TranslationManager.prototype.translateDirective = TM_translateDirective;
- TranslationManager.prototype.translateAttribute = TM_translateAttribute;
- TranslationManager.prototype.translateText = TM_translateText;
- TranslationManager.prototype.translateTag = TM_translateTag;
- TranslationManager.prototype.notifyTagBegin = TM_notifyTagBegin;
- TranslationManager.prototype.notifyTagEnd = TM_notifyTagEnd;
- TranslationManager.prototype.getCurrentTagOffset = TM_getCurrentTagOffset;
- TranslationManager.prototype.getParams = TM_getParams;
- TranslationManager.prototype.searchMatchesCode = TM_searchMatchesCode;
- TranslationManager.prototype.searchMatchesOpenTag = TM_searchMatchesOpenTag;
- TranslationManager.prototype.getMatchingParticipant = TM_getMatchingParticipant
- TranslationManager.prototype.startTagSpan = TM_startTagSpan;
- TranslationManager.prototype.addToTagSpan = TM_addToTagSpan;
- TranslationManager.prototype.addOpenTagToTagSpan = TM_addOpenTagToTagSpan;
- TranslationManager.prototype.addCloseTagToTagSpan = TM_addCloseTagToTagSpan;
- TranslationManager.prototype.finishTagSpan = TM_finishTagSpan;
- TranslationManager.prototype.correctOutlineIDs = TM_correctOutlineIDs;
- TranslationManager.prototype.translateTagSpan = TM_translateTagSpan;
- TranslationManager.prototype.translateTextSpan = TM_translateTextSpan;
- TranslationManager.prototype.startMegaLock = TM_startMegaLock;
- TranslationManager.prototype.addToMegaLock = TM_addToMegaLock;
- TranslationManager.prototype.finishMegaLock = TM_finishMegaLock;
- TranslationManager.prototype.startEditMode = TM_startEditMode;
- TranslationManager.prototype.endEditMode = TM_endEditMode;
- TranslationManager.prototype.setDecoration = TM_setDecoration;
- TranslationManager.prototype.initialize = TM_reInitialize;
- TranslationManager.prototype.participantSort = TM_participantSort;
- TranslationManager.prototype.lookInThisAttribute = TM_lookInThisAttribute;
- TranslationManager.prototype.alwaysCheckAttribute = TM_alwaysCheckAttribute;
- TranslationManager.prototype.lookInThisTag = TM_lookInThisTag;
- TranslationManager.prototype.alwaysCheckTag = TM_alwaysCheckTag;
- TranslationManager.prototype.lookInTags = TM_lookInTags;
- TranslationManager.prototype.pushOpenTag = TM_pushOpenTag;
- TranslationManager.prototype.popCloseTag = TM_popCloseTag;
- TranslationManager.prototype.prepForReparse = TM_prepForReparse;
- TranslationManager.prototype.takeSnapshot = TM_takeSnapshot;
- TranslationManager.prototype.restoreSnapshot = TM_restoreSnapshot;
-
- ///////////////////////////////////////////////
- // Function : TM_reInitialize
- // Purpose : Informs the TSL to reinitialize itself
- ////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////
- function TM_reInitialize()
- {
- this.translator.initiate(this.document, this.translatorClass);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translate
- // Purpose : Utilizes dw.scanSourceString to reliably parse through the given HTML string.
- // Arguments: the HTML string to translate
- // Returns : the translation string as defined by the rules in the XML participant files
- // containing translator sections. This string should be returned by the
- // translators translateMarkup() function.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translate(inStr)
- {
- if (this.index != lastIndex || inStr != lastInStr || this.dynamicTextFormat != lastDynamicTextFormat)
- {
- this.docIsLatin1 = (dw.getDocumentDOM().getCharSet() == "iso-8859-1");
- this.inStr = inStr;
- this.translator.initiate(inStr, this.translatorClass);
- var callback = new TMCallback(this);
- dreamweaver.scanSourceString(inStr, callback);
- while (this.reparse || this.inTagSpan)
- {
- if (this.inTagSpan)
- {
- this.prepForReparse("tagspan");
- // Restart the translator from the beginning of the tag span (in "recover" state)
- this.inTagSpan = false;
- this.tagSpanRecover = true;
- callback.inTagSpan = false;
- }
- else if (this.inMegaLock)
- {
- this.prepForReparse("megalock");
- }
-
- this.reparse = false;
- if (this.reparseSnapshot)
- this.restoreSnapshot(this.reparseSnapshot);
-
- if (debugTranslationMgr)
- alert("Restarting translator due to " +
- (this.inTagSpan ? "tag span (" : "reparse (") +
- this.reparseSnapshot.offset + ")...\n" +
- this.inStr);
-
- dreamweaver.scanSourceString(this.inStr, callback);
- }
- if (this.inMegaLock)
- {
- if (debugMegaLock)
- alert("Open mega lock");
- this.finishMegaLock("");
- }
- var outStr = this.translator.getTranslation();
- this.translator.terminate();
- if (inStr.length != outStr.length)
- {
- lastInStr = inStr;
- lastOutStr = outStr;
- lastIndex = this.index;
- }
- lastDynamicTextFormat = this.dynamicTextFormat;
- }
- else
- {
- outStr = lastOutStr;
- }
-
- return outStr;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_notifyXMLChanged
- // Purpose : Informs the translator that the translatorInfo needs to be refreshed.
- // Call this when the Participant files translator sections have been modified.
- // Since there is no UI currently provided to define the translation rules,
- // developers will need to restart UltraDev when adding/modifying participant
- // files translator sections.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_notifyXMLChange()
- {
- this.requery = true;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_prepForReparse
- // Purpose : Sets up the TM for a reparse of a portion of the document.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_prepForReparse(cause, offset)
- {
- this.reparse = true;
- if (cause == "tagspan")
- this.reparseSnapshot = this.tagSpanSnapshot;
- else if (cause == "megalock")
- this.reparseSnapshot = this.megaLockSnapshot;
- else
- this.reparseSnapshot = new Snapshot(this.enclosingTags, offset);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : evalPattern
- // Purpose : The JavaScript interpreter needs to do some extra work (in
- // js_PutCallObject) whenever it invokes any function containing
- // an eval statement. In order to avoid doing that processing
- // every time that TM_getTranslatorInfo is called, the eval
- // statement is wrapped inside this function.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function evalPattern(pattern)
- {
- return eval(pattern);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getTranslatorInfo
- // Purpose : Build the global multi-dimensional array (translatorInfo) representing the
- // translator information from the XML participant files.
- // Each server model is loaded only once unless requery is set.
- // Note: This is the sole interface between the Translation Manager and the
- // Extension Data Manager (EDM).
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getTranslatorInfo()
- {
- if (this.requery || (translatorInfo[this.index].participants == null))
- {
- // TO DO, if this.requery is true, then we need to destroy the objects in
- // translatorInfo so they too will be reloaded on demand.
-
- // Arrays for partitioning participants by type
- translatorInfo[this.index].participants = 1;
- translatorInfo[this.index].directiveParticipants = new Array();
- translatorInfo[this.index].attributeParticipants = new Array();
- translatorInfo[this.index].textParticipants = new Array();
- translatorInfo[this.index].tagOnlyParticipants = new Array();
- translatorInfo[this.index].outerHTMLParticipants = new Array();
-
- var partArry = dw.getExtParticipants("", "translator");
- if (partArry)
- {
- // Sort participants by priority
-
- var sortValue = 500;
- translatorInfo[this.index].sortOrder = new Array();
- for (var i = 0; i < partArry.length; i++)
- {
- var priority = dw.getExtDataValue(partArry[i], "translator", "priority");
- var type = dw.getExtDataValue(partArry[i], "translator", "type");
- if (type == "renderer")
- {
- continue;
- }
-
- if (priority.length)
- translatorInfo[this.index].sortOrder[partArry[i]] = priority.valueOf();
- else
- translatorInfo[this.index].sortOrder[partArry[i]] = sortValue++;
- }
- partArry.sort(this.participantSort);
-
- // Process each participant in turn (collecting its data)
-
- for (var i = 0; i < partArry.length; i++)
- {
- var type = dw.getExtDataValue(partArry[i], "translator", "type");
- if (type == "renderer")
- {
- continue;
- }
- if (translatorInfo[this.index][partArry[i]] == null)
- {
- translatorInfo[this.index][partArry[i]] = new Array();
- var transInfo = translatorInfo[this.index][partArry[i]];
-
- // === TRANSLATIONS ===
-
- var transArry = dw.getExtDataArray(partArry[i], "translator", "translations");
- if (transArry && transArry.length)
- {
- transInfo.translations = new Array();
-
- for (var j = 0; j < transArry.length; j++)
- {
- // Fill in translatorInfo[this.index].???participants and
- // translatorInfo[this.index][partArry[i]][whereToSearch]
- transData.parse(partArry[i], transArry[j], translatorInfo[this.index], this);
- }
- }
-
- // === CONTEXT ===
-
- var context = dw.getExtDataValue(partArry[i], "translator", "context");
- if (context && context.length)
- transInfo.context = context.toLowerCase();
- else
- transInfo.context = null;
-
- // === MODE ===
- var mode = dw.getExtDataValue(partArry[i], "translator", "mode");
- if (mode && mode.length)
- transInfo.mode = mode.toLowerCase();
- else
- transInfo.mode = null;
-
- // === SEARCH PATTERNS ===
-
- var patternArry = dw.getExtDataArray(partArry[i], "translator", "searchPatterns");
- if (patternArry && patternArry.length)
- {
- transInfo.patterns = new Array();
- transInfo.isPatternRE = new Array();
- transInfo.isOptional = new Array();
- transInfo.requiredLocation = new Array();
- transInfo.paramNames = new Array();
- for (var j = 0; j < patternArry.length; j++)
- {
- var pattern = dw.getExtDataValue(partArry[i], "translator", "searchPatterns", patternArry[j]);
-
- if (this.isPattern(pattern))
- {
- // Any participant with a regular expression in the first search pattern is
- // going to have to be checked against each attribute in each page
- if (j == 0 && !translatorInfo[this.index].lookInAllAttributes)
- if (translatorInfo[this.index].attributeParticipants[partArry[i]])
- translatorInfo[this.index].lookInAllAttributes = true;
- transInfo.isPatternRE[patternArry[j]] = true;
- transInfo.patterns[patternArry[j]] = evalPattern(pattern);
- }
- else
- {
- // Any participant with a string in the first search pattern is only
- // going to have to be checked against each attribute in each page if
- // that string doesn't match one of our predictable patterns
- if (j == 0 && !translatorInfo[this.index].lookInAllAttributes)
- if (translatorInfo[this.index].attributeParticipants[partArry[i]])
- if (!this.alwaysCheckAttribute(pattern))
- translatorInfo[this.index].lookInAllAttributes = true;
- transInfo.isPatternRE[patternArry[j]] = false;
- transInfo.patterns[patternArry[j]] = pattern;
- }
-
- var isOptional =
- dw.getExtDataValue(partArry[i], "translator", "searchPatterns", patternArry[j], "isOptional");
- transInfo.isOptional[patternArry[j]] = (isOptional.toLowerCase() == "true");
-
- var requiredLocation =
- dw.getExtDataValue(partArry[i], "translator", "searchPatterns", patternArry[j], "requiredLocation").toLowerCase();
- transInfo.requiredLocation[patternArry[j]] = "";
- if (requiredLocation == "leading" ||
- requiredLocation == "trailing" ||
- requiredLocation == "opentag" ||
- requiredLocation == "tagname")
- transInfo.requiredLocation[patternArry[j]] = requiredLocation;
- var paramNames = dw.getExtDataValue(partArry[i], "translator", "searchPatterns", patternArry[j], "paramNames");
- if (paramNames && paramNames.length)
- transInfo.paramNames[patternArry[j]] = paramNames;
- }
- }
- }
- }
- }
- this.requery = false;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_lookInThisAttribute
- // Purpose : Used within the TM_callback class to see if it necessary to look
- // within this particular attribute to check for a translation rule.
- // This is an optimization that allows us to ignore looping through
- // all participants with translation rules for most attributes. It
- // relies on the fact that our current translation rules for attributes
- // all have quicksearches defined (non-regular expression search pattern)
- // that contain certain known character sequences (ie. '<%', '#', '<cf',
- // and '<jsp:'). If a developer extends these any of our translators in
- // such a way that their quick search pattern does not exist or is not one
- // of these expressions, then this performance boost will not kick in since
- // we will not be able to quickly reject most attributes.
- // Arguments: code : this is the attribute value passed into the attribute callback method.
- // Returns : false if we can quickly reject this attribute value (i.e we dont need to
- // search within the attribute participants for a pattern that matches this code.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_lookInThisAttribute(code)
- {
- this.getTranslatorInfo();
- if (translatorInfo[this.index].lookInAllAttributes)
- return true;
- else if (this.alwaysCheckAttribute(code))
- return true;
- return false;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_alwaysCheckAttribute
- // Purpose : Allows server models to specify their own attribute character
- // sequences for the optimization implemented in TM_lookInThisAttribute.
- // See myAlwaysCheckAttribute in JSP.htm for an example.
- // Arguments: code = quicksearch pattern or code from TMCallback attribute function
- // Returns : true = try to translate attribute, false = skip attribute
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_alwaysCheckAttribute(code)
- {
- if (this.serverModelAlwaysCheckAttribute != null)
- return this.serverModelAlwaysCheckAttribute(code);
- else
- return false;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_lookInThisTag
- // Purpose : Used within the TM_callback class to see if it necessary to look
- // within this particular tag to check for a translation rule.
- // This is an optimization that allows us to ignore looping through
- // all participants with translation rules for most tags. It
- // relies on the fact that our current translation rules for tags
- // apply only to tags with known prefixes (like "jsp:" or "cf")
- // If a developer adds a translation rule for a tag that doesn't
- // start with one of these prefixes, then this performance boost will
- // not kick in since we will not be able to quickly reject most tags.
- // Arguments: tagName
- // Returns : false if we can quickly reject this tag (i.e we dont need to search
- // within the tag participants for a pattern that matches this code).
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_lookInThisTag(tagName)
- {
- this.getTranslatorInfo();
- if (translatorInfo[this.index].lookInAllTags)
- return true;
- else if (this.alwaysCheckTag(tagName))
- return true;
- return false;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_alwaysCheckTag
- // Purpose : Allows server models to specify their own tag tests for the optimization
- // implemented in TM_lookInThisTag. See myAlwaysCheckTag in JSP.htm
- // for an example.
- // Arguments: tagName
- // Returns : true = try to translate this tag, false = skip this tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_alwaysCheckTag(tagName)
- {
- if (this.serverModelAlwaysCheckTag != null)
- return this.serverModelAlwaysCheckTag(tagName);
- else
- return false;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_lookInTags
- // Purpose : DEPRECATED
- // Arguments:
- // Returns : true if any participant for the current server model contains a tag
- // search.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_lookInTags()
- {
- return translatorInfo[this.index].lookInAllTags;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_participantSort
- // Purpose : Sorts participants based on the priority attribute of the translator tag
- // Arguments: ptype - the callback location where dw.scanSourceString found the code fragment
- // code - the code fragment to match against the XML patterns
- // Returns : Name of the participant that matches the code segment and location requirement,
- // null if none found.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_participantSort(part1, part2)
- {
- var result = 0;
- var priority1 = translatorInfo[g_index].sortOrder[part1];
- var priority2 = translatorInfo[g_index].sortOrder[part2];
- if (priority1 != priority2)
- {
- if (priority1 < priority2)
- {
- result = -1;
- }
- else
- {
- result = 1;
- }
- }
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getParticipant
- // Purpose : Find the participant whose search and location specification matches the
- // specified code fragment.
- // Arguments: ptype - the callback location where dw.scanSourceString found the code fragment
- // code - the code fragment to match against the XML patterns
- // Returns : Name of the participant that matches the code segment and location requirement,
- // null if none found.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getParticipant(pType, code)
- {
- var participant = null;
- if (pType == PTYPE_ATTRIBUTE)
- {
- participant = this.getAttribute(code, TM_getParticipant.arguments[2]);
- }
- else
- {
- if (pType == PTYPE_TAG)
- {
- participant = this.getTag(code);
- }
- else
- {
- if (pType == PTYPE_TEXT)
- {
- participant = this.getText(code);
- }
- else
- {
- if (pType == PTYPE_DIRECTIVE)
- {
- participant = this.getDirective(code);
- }
- }
- }
- }
- return participant;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getDirective
- // Purpose : Find the participant whose translation name is "directive" and pattern
- // successfuly identifies the specified code segment.
- // Arguments: code - directive from dw.scanSourceString directive callback.
- // Returns : Matching participant, otherwise null.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getDirective(code)
- {
- var participant = null;
- this.getTranslatorInfo();
- var index = "directive";
- var arry = translatorInfo[this.index];
-
- if (arry.directiveParticipants)
- {
- for (var part in arry.directiveParticipants)
- {
- var translations = arry[part].translations;
- if (translations)
- {
- if (translations[index])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index;
- participant = part;
- break;
- }
- }
- }
- }
- }
- return participant;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getText
- // Purpose : Find the participant whose translation name is "text" and pattern
- // successfuly identifies the specified code segment.
- // Arguments: code - text span from dw.scanSourceString text callback.
- // Returns : Matching participant, otherwise null.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getText(code)
- {
- var participant = null;
- this.getTranslatorInfo();
- var index = "text";
- var arry = translatorInfo[this.index];
-
- if (arry.textParticipants)
- {
- for (var part in arry.textParticipants)
- {
- var translations = arry[part].translations;
- if (translations)
- {
- if (translations[index])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index;
- participant = part;
- break;
- }
- }
- }
- }
- }
- return participant;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getTag
- // Purpose : Find the participant whose translation name is equivalent to the current tag name
- // or "*", and whose pattern successfuly identifies the specified code segment.
- // Priority is given to participants whose translation name matches the current tag.
- // If no participant is found, then we search for the wild card tag specification "*".
- // Arguments: code - tag span collected between the dw.scanSourceString openTagBegin
- // and openTagEnd callbacks and the tag span between the closeTagBegin and closeTagEnd
- // callbacks.
- // Returns : Matching participant, otherwise null.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getTag(code)
- {
- var participant = null;
- this.getTranslatorInfo();
- var tag = this.getCurrentTagName();
- var index = "tag+" + tag + ":tagonly";
- var index2 = "tag+*:tagonly";
- var arry = translatorInfo[this.index];
-
- if (arry.tagOnlyParticipants)
- {
- for (var part in arry.tagOnlyParticipants)
- {
- var translations = arry[part].translations;
- if (translations)
- {
- if (translations[index])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index;
- participant = part;
- break;
- }
- }
- if (!participant)
- {
- if (translations[index2])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index2;
- participant = part;
- }
- }
- }
- }
- }
- }
- return participant;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getAttribute
- // Purpose : Find the participant whose translation name is equivalent to the current
- // tag+attribute pair or "*+*", and whose pattern successfuly identifies the
- // specified code segment.
- // Priority is given to participants whose translation name matches the current
- // tag+attribute pair.
- // If no participant is found, then we search for the wild card tag+attribute
- // specification "*+*".
- // Arguments: code - attribute value from dw.scanSourceString attribute callback.
- // attrName - attribute name from dw.scanSourceString attribute callback.
- // Returns : Matching participant, otherwise null.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getAttribute(code, attrName)
- {
- var participant = null;
- this.getTranslatorInfo();
- var tag = "tag+" + this.getCurrentTagName();
- var attribute = "attribute+" + attrName.toLowerCase();
- var index = tag + ":" + attribute;
- var index2 = tag + ":attribute+*";
- var index3 = "tag+*:attribute+*";
- var arry = translatorInfo[this.index];
-
- if (arry.attributeParticipants)
- {
- for (var part in arry.attributeParticipants)
- {
- var translations = arry[part].translations;
- if (translations)
- {
- if (translations[index])
- {
- // Look for specific tag + attribute matches first
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index;
- participant = part;
- break;
- }
- }
- if (!participant)
- {
- if (translations[index2])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index2;
- participant = part;
- }
- }
- }
- if (!participant)
- {
- if (translations[index3])
- {
- if (this.searchMatchesCode(part, code))
- {
- this.whereToSearch = index3;
- participant = part;
- }
- }
- }
- }
- }
- }
- return participant;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getParams
- // Purpose : pulls parameters out of regular expression match
- // Arguments: params - array of params to add to
- // paramNames - comma delimited list of param names
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getParams(params, paramNames, doEncode)
- {
- if (paramNames && paramNames.length)
- {
- var paramArry = paramNames.split(",");
- if (paramArry[0] && paramArry[0].length)
- {
- params[paramArry[0]] = RegExp.$1;
- if (doEncode)
- params[paramArry[0]] = dw.latin1ToNative(params[paramArry[0]]);
- }
- if (paramArry[1] && paramArry[1].length)
- {
- params[paramArry[1]] = RegExp.$2;
- if (doEncode)
- params[paramArry[1]] = dw.latin1ToNative(params[paramArry[1]]);
- }
- if (paramArry[2] && paramArry[2].length)
- {
- params[paramArry[2]] = RegExp.$3;
- if (doEncode)
- params[paramArry[2]] = dw.latin1ToNative(params[paramArry[2]]);
- }
- if (paramArry[3] && paramArry[3].length)
- {
- params[paramArry[3]] = RegExp.$4;
- if (doEncode)
- params[paramArry[3]] = dw.latin1ToNative(params[paramArry[3]]);
- }
- if (paramArry[4] && paramArry[4].length)
- {
- params[paramArry[4]] = RegExp.$5;
- if (doEncode)
- params[paramArry[4]] = dw.latin1ToNative(params[paramArry[4]]);
- }
- if (paramArry[5] && paramArry[5].length)
- {
- params[paramArry[5]] = RegExp.$6;
- if (doEncode)
- params[paramArry[5]] = dw.latin1ToNative(params[paramArry[5]]);
- }
- if (paramArry[6] && paramArry[6].length)
- {
- params[paramArry[6]] = RegExp.$7;
- if (doEncode)
- params[paramArry[6]] = dw.latin1ToNative(params[paramArry[6]]);
- }
- if (paramArry[7] && paramArry[7].length)
- {
- params[paramArry[7]] = RegExp.$8;
- if (doEncode)
- params[paramArry[7]] = dw.latin1ToNative(params[paramArry[7]]);
- }
- if (paramArry[8] && paramArry[8].length)
- {
- params[paramArry[8]] = RegExp.$9;
- if (doEncode)
- params[paramArry[8]] = dw.latin1ToNative(params[paramArry[8]]);
- }
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_searchMatchesOpenTag
- // Purpose : determines whether the specified code matches the search patterns with
- // requiredLocation="opentag". This can be used to eliminate some tag spans
- // from consideration before we bother collecting the whole tag span.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_searchMatchesOpenTag(part, code)
- {
- var found = true;
- var arry = translatorInfo[this.index][part];
-
- if (arry.context)
- {
- var top = null;
- if (this.enclosingTags.length > 0)
- top = this.enclosingTags[this.enclosingTags.length-1];
- if (arry.context != top)
- return false;
- }
-
- if (arry.mode)
- {
- if (arry.mode != this.mode)
- return false;
- }
-
- if (arry.patterns)
- {
- for (var patternName in arry.patterns)
- {
- if (arry.requiredLocation[patternName] == "opentag")
- {
- var isRE = arry.isPatternRE[patternName];
- var pattern = arry.patterns[patternName];
- if (!isRE)
- {
- var offset = code.indexOf(pattern);
- }
- else
- {
- if (this.docIsLatin1)
- {
- code = dw.nativeToLatin1(code);
- }
- var offset = code.search(pattern);
- }
- if (offset == -1 && !arry.isOptional[patternName])
- {
- found = false;
- break;
- }
- }
- else if (arry.requiredLocation[patternName] == "tagname")
- {
- var tagName = this.currentTagName;
- var isRE = arry.isPatternRE[patternName];
- var pattern = arry.patterns[patternName];
- if (!isRE)
- {
- var offset = tagName.indexOf(pattern);
- }
- else
- {
- if (this.docIsLatin1)
- {
- tagName = dw.nativeToLatin1(tagName);
- }
- var offset = tagName.search(pattern);
- }
- if (offset == -1 && !arry.isOptional[patternName])
- {
- found = false;
- break;
- }
- }
- }
- }
-
- return found;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_searchMatchesCode
- // Purpose : determines weather the specified code satisfies the search criteria defined
- // within the XML participant translator, patterns section.
- // Multiple ordered searches supported.
- // Arguments: part - participant name
- // code - code fragment to run patterns agains
- // Returns : true if match, false otherwise
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_searchMatchesCode(part, code)
- {
- var found = false;
- var params = new Array();
- var arry = translatorInfo[this.index][part];
-
- if (arry.context)
- {
- var top = null;
- if (this.enclosingTags.length > 0)
- top = this.enclosingTags[this.enclosingTags.length-1];
- if (arry.context != top)
- return false;
- }
-
- if (arry.mode)
- {
- if (arry.mode != this.mode)
- return false;
- }
-
- if (arry.patterns)
- {
- for (var patternName in arry.patterns)
- {
- var isRE = arry.isPatternRE[patternName];
- var pattern = arry.patterns[patternName];
- if (!isRE)
- {
- if (arry.requiredLocation[patternName] == "")
- {
- var offset = code.indexOf(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "leading")
- {
- var offset = this.inStr.substr(0, this.getCurrentTagOffset()).indexOf(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "trailing")
- {
- var offset = this.inStr.substr(this.getCurrentTagOffset() + code.length).indexOf(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "opentag")
- {
- var tagLength = TranslationManager.findTagLength(code);
- if (tagLength != -1)
- var offset = code.substr(0, tagLength).indexOf(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "tagname")
- {
- var offset = this.currentTagName.indexOf(pattern);
- }
- }
- }
- }
- }
- }
- else
- {
- if (arry.requiredLocation[patternName] == "")
- {
- if (this.docIsLatin1)
- {
- code = dw.nativeToLatin1(code);
- }
- var offset = code.search(pattern);
- if (offset != -1)
- {
- var paramNames = arry.paramNames[patternName];
- this.getParams(params, paramNames, this.docIsLatin1);
- }
- }
- else
- {
- if (arry.requiredLocation[patternName] == "leading")
- {
- var offset = this.inStr.substr(0, this.getCurrentTagOffset()).search(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "trailing")
- {
- var offset = this.inStr.substr(this.getCurrentTagOffset() + code.length).search(pattern);
- }
- else
- {
- if (arry.requiredLocation[patternName] == "opentag")
- {
- var tagLength = TranslationManager.findTagLength(code);
- if (tagLength != -1)
- {
- var tagCode = code.substr(0, tagLength);
-
- if (this.docIsLatin1)
- {
- tagCode = dw.nativeToLatin1(tagCode);
- }
- var offset = tagCode.search(pattern);
- if (offset != -1)
- {
- var paramNames = arry.paramNames[patternName];
- this.getParams(params, paramNames, this.docIsLatin1);
- }
- }
- }
- else
- {
- if (arry.requiredLocation[patternName] == "tagname")
- {
- var tagName = this.currentTagName;
- if (this.docIsLatin1)
- {
- tagName = dw.nativeToLatin1(tagName);
- }
- var offset = tagName.search(pattern);
- if (offset != -1)
- {
- var paramNames = arry.paramNames[patternName];
- this.getParams(params, paramNames, this.docIsLatin1);
- }
- }
- }
- }
- }
- }
- }
-
- if (offset != -1)
- {
- found = true;
- }
- else
- {
- if (!arry.isOptional[patternName])
- {
- found = false;
- break;
- }
- }
- }
- }
- this.params = params;
-
- return found;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getData
- // Purpose : Retreive the translation information for the given participant.
- // Token substitution provided using the specified code fragment.
- // Arguments: part - participant name
- // code - code for which participant was located
- // Returns : transData structure which contains the openTag, closeTag, display, attributes, etc.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getData(part, code, attrName)
- {
- var data = null;
- if (part)
- {
- var whereToSearch = this.whereToSearch;
- var arry = translatorInfo[this.index][part].translations;
- if (arry)
- {
- if (arry[whereToSearch])
- {
- data = transData.copy(arry[whereToSearch].data);
- var tokens = this.getTokens(part, code, attrName);
- data.replaceTokens(tokens);
- }
- }
- }
- return data;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getTokens(part)
- // Purpose : retreive the translation token patterns for the specified participant
- // Arguments: part - participant
- // Returns : An array indexed by the token names, containing the token patterns
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getTokens(part, code, attrName)
- {
- var tokens = new Array();
- if (attrName && attrName != "")
- {
- tokens["attr"] = attrName;
- }
- for (var paramName in this.params)
- {
- tokens[paramName] = this.params[paramName];
- }
- return tokens;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_isPattern
- // Purpose : determines whether a string is a regular expression
- // Arguments: pattern - regular expression or quick search expression (locate using indexOf)
- // Returns : true if regular expression, false otherwise
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_isPattern(pattern)
- {
- if (pattern.charAt(0) == "/")
- {
- return true;
- }
- return false;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getCurrentTagName
- // Purpose : Get the name of the active tag. Used from openTagEnd, closeTagEnd, and
- // attribute callbacks.
- // Arguments: Pass in optional attribute offset, when called from attribute callback.
- // Returns : Active tag name;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getCurrentTagName()
- {
- return this.currentTagName;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getCurrentTag
- // Purpose : returns active tag - example <cfoutput querry-"">
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getCurrentTag()
- {
- var currTag = "";
- if ((this.offsetTagBegin >= 0) && (this.offsetTagEnd >= 0))
- {
- currTag = this.inStr.substr(this.offsetTagBegin, this.offsetTagEnd - this.offsetTagBegin);
- }
- return currTag;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getCurrentTagOffset
- // Purpose : returns offset of beginning of active tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getCurrentTagOffset()
- {
- return this.offsetTagBegin;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_notifyTagBegin
- // Purpose : returns active tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_notifyTagBegin(tag, offset)
- {
- this.currentTagName = tag.toLowerCase();
- this.offsetTagBegin = offset;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_notifyTagEnd
- // Purpose : returns active tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_notifyTagEnd(offset)
- {
- this.offsetTagEnd = offset;
- return this.getCurrentTag();
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateDirective
- // Purpose : translate the directive given the translation rules (utilizes the dependent search criteria info)
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateDirective(code, offset, trans)
- {
- var origPosition = this.translator.getPosition();
- var result = "";
- if (trans)
- {
- result = this.translator.translateDirective(code, offset, trans.participant, trans.type, trans.openTag, trans.closeTag, trans.attributes, trans.display, trans.lockAttributes);
- }
- else if (this.defaultDirectiveTag != this.translatorClass)
- {
- result = this.translator.translateDirective(code, offset, "script", "", this.defaultDirectiveTag, this.defaultDirectiveTag, "", "", "");
- }
- else
- {
- result = this.translator.translateDirective(code, offset, "script", "", "", "", "", "", "");
- }
- if (this.inMegaLock)
- {
- var preCode = this.inStr.substr(origPosition, offset-origPosition);
- this.addToMegaLock(preCode, code, result);
- }
- else if (this.inEditMode)
- {
- this.editModeFullTranslation.add(result);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateText
- // Purpose : translate the text given the translation rules
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateText(code, offset, trans)
- {
- var origPosition = this.translator.getPosition();
- var result = new Object();
- result.reparse = false;
- result.translation = "";
- if (trans)
- {
- if (trans.insertBefore)
- {
- result.translation += this.translator.translateText("", offset, trans.participant, "as is", "", "", "", trans.insertBefore, "");
- }
-
- result.translation += this.translator.translateText(code, offset, trans.participant, trans.type, trans.openTag, trans.closeTag, trans.attributes, trans.display, trans.lockAttributes);
-
- if (trans.insertAfter)
- {
- result.translation += this.translator.translateText("", offset+code.length, trans.participant, "as is", "", "", "", trans.insertAfter, "");
- }
- if (trans.reparse)
- {
- result.reparse = true;
- result.useEditMode = trans.useEditMode;
- }
- }
- else
- {
- result.translation = this.translator.translateText(code, offset, "", "", "", "", "", "", "");
- }
- if (this.inMegaLock)
- {
- var preCode = this.inStr.substr(origPosition, offset-origPosition);
- this.addToMegaLock(preCode, code, result.translation);
- }
- else if (this.inEditMode)
- {
- this.editModeFullTranslation.add(result);
- }
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateAttribute
- // Purpose : translate the attribute given the translation rules
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateAttribute(code, name, trans)
- {
- if (trans)
- {
- if ((this.translatorClass == "MM_CFML") && ((trans.type == "dynamic data") || (trans.type == "dynamic image")) && trans.participant != "DynamicAttribute")
- {
- if (this.CFOutput.IsEmpty())
- {
- // Need to enforce that cfoutput tags surround the dynamic data
- if (code.search(/<cfoutput\s*>/i) == -1 || code.search(/<\/cfoutput\s*>/i) == -1)
- {
- trans = null;
- }
- }
- }
- }
- if (trans)
- {
- this.translator.translateAttribute(code, name, trans.type, trans.attributes);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : evalExternalFunction
- // Purpose : The JavaScript interpreter needs to do some extra work (in
- // js_PutCallObject) whenever it invokes any function containing
- // an eval statement. In order to avoid doing that processing
- // every time that TM_translateTag is called, the eval
- // statement is wrapped inside this function.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function evalExternalFunction(funcName, code, transMgr)
- {
- var functionCall = funcName + "(code, transMgr);";
- return eval(functionCall);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateTag
- // Purpose : translate the tag given the translation rules
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateTag(code, offset, trans)
- {
- var origPosition = this.translator.getPosition();
- var translation = "";
- if (trans && trans.type == "external")
- {
- trans = evalExternalFunction(trans.display, code, this);
- }
-
- if (trans && trans.beginMegaLock)
- {
- this.startMegaLock(offset);
- }
-
- if (trans)
- {
- if (trans.insertBefore)
- {
- translation += this.translator.translateText("", offset, trans.participant, "as is", "", "", "", trans.insertBefore, "");
- }
-
- translation += this.translator.translateTag(code, offset, trans.participant, trans.type, trans.openTag, trans.closeTag, trans.attributes, trans.display, trans.lockAttributes);
-
- if (trans.insertAfter)
- {
- translation += this.translator.translateText("", offset+code.length, trans.participant, "as is", "", "", "", trans.insertAfter, "");
- }
- }
- else
- {
- translation = this.translator.translateTag(code, offset, "", "", "", "", "", "", "");
- }
-
- if (this.inMegaLock)
- {
- var preCode = this.inStr.substr(origPosition, offset-origPosition);
- this.addToMegaLock(preCode, code, translation);
- }
- else if (this.inEditMode)
- {
- this.editModeFullTranslation.add(translation);
- }
-
- if (trans && trans.endMegaLock)
- {
- translation = this.finishMegaLock(trans.lockAttributes);
- }
-
- var endOffset = offset + code.length;
- if (this.inEditMode && (endOffset >= this.editModeEndOffset))
- {
- this.endEditMode();
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_findTagLength
- // Purpose : look ahead and find the ">" that matches this "<".
- // Ignore any script blocks (e.g. <% %>) you find on the way.
- // Return the length of the tag.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_findTagLength(searchString)
- {
- // Counter to match pairs of < and >. Starts at 1
- // because we start looking after the first <.
- var counter = 1;
-
- // Start after the first <. Stop after the matching >.
- for (var i = 1; i < searchString.length && counter > 0; i++)
- {
- if (searchString[i] == '<')
- counter++;
- else if (searchString[i] == '>')
- counter--;
- }
-
- if (i == searchString.length && counter > 0)
- return -1;
- else
- return i;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getAttributeValue
- // Purpose : pull the ID attribute for the current tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_getAttributeValue(code, attrName)
- {
- var tagLength = TranslationManager.findTagLength(code);
- var tag = code.substr(0, tagLength);
-
- var value = "";
- var expression;
-
- // name="value"
- expression = new RegExp(attrName + "\\s*=\\s*\"(((<%.*?%>)|[^<\">])*)\"", "i");
- if (tag.match(expression))
- value = RegExp.$1;
-
- // name='value'
- expression = new RegExp(attrName + "\\s*=\\s*'(((<%.*?%>)|[^<'>])*)'", "i");
- if (value == "" && tag.match(expression))
- value = RegExp.$1;
-
- // name=value
- expression = new RegExp(attrName + "\\s*=\\s*(((<%.*?%>)|[^ \t\n<\"'>])*)", "i");
- if (value == "" && tag.match(expression))
- value = RegExp.$1;
-
- return value;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Function : TM_splitBody
- // Purpose : Static function to locate the contents of the <body>
- // tag and split the document at its boundaries. It will only attempt
- // this split if the document has a single pair of <body> tags. Some
- // server models can use this to skip over the tags outside the body
- // (which don't need to be translated).
- ///////////////////////////////////////////////////////////////////////////
- function TM_splitBody(inStr)
- {
- var result = new Object();
-
- result.preInStr = "";
- result.inStr = inStr;
- result.postInStr = "";
-
- var callback = new Object();
- callback.openTagCount = 0;
- callback.closeTagCount = 0;
- callback.innerStart = -1;
- callback.innerEnd = -1;
- callback.openTagBegin = new Function("tag,offset","if (tag.toUpperCase() == \"BODY\") { this.openTagCount++; }");
- callback.openTagEnd = new Function("offset","if (this.openTagCount == 1 && this.innerStart == -1) { this.innerStart = offset; }");
- callback.closeTagBegin = new Function("tag,offset","if (tag.toUpperCase() == \"BODY\") { this.innerEnd = offset; this.closeTagCount++; }");
-
- dw.scanSourceString(inStr, callback);
-
- if (callback.innerStart >= 0 && callback.innerEnd >= 0 &&
- callback.openTagCount == 1 && callback.closeTagCount == 1)
- {
- result.preInStr = inStr.substring(0, callback.innerStart);
- result.postInStr = inStr.substring(callback.innerEnd);
- result.inStr = inStr.substring(callback.innerStart, callback.innerEnd);
-
- // DEBUG DWfile.write("C:\\TM_splitBody.txt", "preInStr = " + result.preInStr + "\r\n\r\npostInStr = " + result.postInStr + "\r\n\r\ninStr = " + result.inStr);
- }
- else
- {
- // DEBUG DWfile.write("C:\\TM_splitBody.txt", "failed " + callback.openTagCount + ", " + callback.closeTagCount);
- }
-
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateTagSpan
- // Purpose : translate the tag span given the translation rules
- // Tag span defined to be a span of the document from the open tag to its close tag
- // For example <cfoutput>#a.b#</cfoutput> is a tag span
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateTagSpan(code, offset, trailingFormat)
- {
- if (this.tagSpanRecover)
- {
- this.tagSpanRecover = false;
- return false;
- }
-
- var tag = this.getCurrentTagName();
- tag = tag.toLowerCase();
- this.getTranslatorInfo();
-
- var index = "tag+" + tag + ":all";
- var index2 = "tag+*:all";
- var arry = translatorInfo[this.index];
-
- var inTagSpan = false;
-
- var possibleParticipants = null;
-
- if (arry.outerHTMLParticipants)
- {
- for (var part in arry.outerHTMLParticipants)
- {
- if (!arry[part].mode || arry[part].mode == this.mode)
- {
- var translations = arry[part].translations;
- if (translations)
- {
- // Check context, mode, and any search patterns with requiredLocation="openTag" or "tagName"
- if ((translations[index] || translations[index2]) && this.searchMatchesOpenTag(part, code))
- {
- if (possibleParticipants == null)
- possibleParticipants = new Array();
- possibleParticipants.push(part);
- }
- }
- }
- }
- }
-
- if (possibleParticipants != null)
- {
- this.startTagSpan(tag, offset - code.length, possibleParticipants);
- inTagSpan = true;
- }
-
- return inTagSpan;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_startTagSpan
- // Purpose : Enter the tag span state. All new tags and text will go into
- // the current tag span
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function TM_startTagSpan(tagName, offset, participants)
- {
- if (debugTagSpan)
- alert("startTagSpan..." + tagName);
- this.tagSpan = new QuickString();
- this.inTagSpan = true;
- this.tagSpanName = tagName;
- this.tagSpanCounter = 0;
- this.tagSpanParts = participants;
- this.tagSpanSnapshot = new Snapshot(this.enclosingTags, offset);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_addToTagSpan
- // Purpose : Add text to the current tag span.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function isWhiteSpace(x)
- {
- return x == '\r' || x == '\n' || x == '\t' || x == ' ';
- }
-
- function TM_addToTagSpan(code, offset)
- {
- var whitespace = "";
- if (this.tagSpanLastIndex != -1)
- {
- // White space and invalid tags don't generate a call to translateText, so
- // we need to slurp in any text that's occured since the last addToTagSpan
- extraText = this.inStr.substr(this.tagSpanLastIndex, offset-this.tagSpanLastIndex);
- this.tagSpan.add(extraText);
- }
- this.tagSpan.add(code);
- this.tagSpanLastIndex = offset + code.length;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_addOpenTagToTagSpan
- // Purpose : Add open tag to the current tag span. Keep track of nested
- // tags (e.g. <foo><foo></foo></foo>) with the tagSpanCounter.
- // Returns : true = continue parsing, false = stop parsing
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function TM_addOpenTagToTagSpan(code, offset, trailingFormat)
- {
- if (debugTagSpan)
- alert("addOpenTagToTagSpan..." + code);
-
- var openPattern = new RegExp("^<" + this.tagSpanName + "\\b", "i");
-
- //if (this.tagSpanCounter == 0) // first tag
- if (this.tagSpanSnapshot.offset == offset-code.length) // first tag
- this.tagSpanLastIndex = -1;
- this.addToTagSpan(code, offset-code.length);
-
- var isComplete = (trailingFormat.length > 0 &&
- trailingFormat[trailingFormat.length-1] == '/');
- if (!isComplete && (code.search(openPattern) != -1))
- this.tagSpanCounter++;
-
- if (isComplete && this.tagSpanCounter == 0)
- return this.finishTagSpan();
-
- var continueTagSpan = new Object();
- continueTagSpan.success = false;
- continueTagSpan.inTagSpan = true;
- continueTagSpan.reparse = false;
- return continueTagSpan;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_addCloseTagToTagSpan
- // Purpose : Add close tag to the current tag span. Keep track of nested
- // tags with the tagSpanCounter. If this is the end of the tag span, try
- // to translate it. If translation is impossible, stop parsing (we'll have
- // to start over).
- // Returns : true = continue parsing, false = stop parsing
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function TM_addCloseTagToTagSpan(code, offset)
- {
- if (debugTagSpan)
- alert("addCloseTagToTagSpan..." + code);
-
- var closePattern = new RegExp("^</" + this.tagSpanName + "\\b", "i");
-
- this.addToTagSpan(code, offset-code.length);
- if (code.search(closePattern) != -1)
- this.tagSpanCounter--;
-
- if (this.tagSpanCounter == 0)
- {
- return this.finishTagSpan();
- }
-
- var continueTagSpan = new Object();
- continueTagSpan.success = false;
- continueTagSpan.inTagSpan = true;
- continueTagSpan.reparse = false;
- return continueTagSpan;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_finishTagSpan
- // Purpose : Try to translate the tag span.
- // Returns : true = continue parsing, false = stop parsing
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function TM_finishTagSpan()
- {
- var origPosition = this.translator.getPosition();
- if (this.inMegaLock)
- {
- // If we end up reparsing this tag span because there isn't a
- // participant match, we need to have already inserted any leading
- // whitespace into the mega lock before that happens.
- var preCode = this.inStr.substr(origPosition, this.tagSpanSnapshot.offset-origPosition);
- this.addToMegaLock(preCode, "", "");
- }
-
- var success = new Object();
- success.success = true;
- success.inTagSpan = false;
- success.reparse = false;
-
- var failure = new Object();
- failure.success = false;
- failure.inTagSpan = true;
- failure.reparse = true;
-
- var translation;
- var tagSpanString = this.tagSpan.toString();
-
- if (debugTagSpan)
- alert("finishTagSpan...\n" + tagSpanString);
-
- if (this.tagSpanCache) // Use cached translation if available
- {
- translation = this.tagSpanCache.getTranslation(tagSpanString);
- if (translation)
- {
- translation = this.correctOutlineIDs(translation);
- // alert("CACHED TRANSLATION\n==========\n" + tagSpanString +
- // "\n===========\n" + translation);
- this.translator.insertTranslation(tagSpanString, this.tagSpanSnapshot.offset, translation);
- this.inTagSpan = false;
-
- return success;
- }
- }
-
- var index = "tag+" + this.tagSpanName + ":all";
- var index2 = "tag+*:all";
- var part = this.getMatchingParticipant(index, index2,
- this.tagSpanParts, tagSpanString);
-
- if (part != null)
- {
- var trans = this.getData(part, tagSpanString);
-
- if (trans && trans.type == "external")
- {
- trans = evalExternalFunction(trans.display, tagSpanString, this);
- // External functions for tag spans can return null to force the
- // various components of the tag span to be parsed separately.
- if (trans == null)
- return failure;
- }
-
- if (trans && trans.beginMegaLock)
- {
- this.startMegaLock(this.tagSpanSnapshot.offset);
- }
-
- // use AppendText to prevent translated attributes being
- // appended to the end tag
- var result = this.translateText(tagSpanString, this.tagSpanSnapshot.offset, trans);
-
- if (trans && trans.endMegaLock)
- {
- result.translation = this.finishMegaLock(trans.lockAttributes);
- }
-
- if (result.reparse)
- {
- if (result.useEditMode)
- {
- this.startEditMode(this.tagSpanSnapshot.offset + tagSpanString.length,
- tagSpanString,
- result.translation);
- }
- // We need to leave this.inTagSpan on here, so that the next parse
- // works on the individual tags instead of the whole span
- return failure;
- }
-
- if (this.tagSpanCache) // Store translation in cache if available
- {
- this.tagSpanCache.setTranslation(tagSpanString, result.translation);
- }
-
- if (this.inMegaLock)
- {
- // We already inserted the precode at the top of this function.
- this.addToMegaLock("", tagSpanString, result.translation);
- }
-
- this.inTagSpan = false;
- return success;
- }
- else
- {
- return failure;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_correctOutlineIDs
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_correctOutlineIDs(translation)
- {
- var oldBaseId = null;
- var newBaseId = this.translator.getOutlineId();
- var outlineId = null;
- var attr = "mmTranslatedValueOutlineID=\"OUTLINEID=";
-
- var translationPieces = translation.split(attr);
- for (var i = 1; i < translationPieces.length; i++)
- {
- translationPieces[i] =
- translationPieces[i].replace(/^([0-9]*)\"/, "\"");
- if (oldBaseId == null)
- oldBaseId = RegExp.$1;
- outlineId = RegExp.$1 - oldBaseId + newBaseId;
- translationPieces[i] = outlineId + translationPieces[i];
- }
-
- this.translator.setOutlineId(outlineId);
- return translationPieces.join("mmTranslatedValueOutlineID=\"OUTLINEID=");
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_getMatchingParticipant
- // Purpose : Find a participant that matches our tag.
- // Arguments: specIndex = specific index (e.g. "tag+foo:all")
- // genIndex = general index (e.g. "tag+*:all")
- // partArray = array of available participants
- // code = stuff to try to match
- // Returns : true = continue parsing, false = stop parsing
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- function TM_getMatchingParticipant(specIndex, genIndex, partArray, code)
- {
- var part = null;
- var arry = translatorInfo[this.index];
-
- for (index in partArray)
- {
- var possiblePart = partArray[index];
- var translations = arry[possiblePart].translations;
- if (translations)
- {
- if (translations[specIndex])
- {
- // translationType="none" skips the translation
- if (translations[specIndex].data.type == "none")
- return null;
- if (this.searchMatchesCode(possiblePart, code))
- {
- this.whereToSearch = specIndex;
- part = possiblePart;
- break;
- }
- }
- if (!part)
- {
- if (translations[genIndex])
- {
- // translationType="none" skips the translation
- if (translations[genIndex].data.type == "none")
- return null;
- if (this.searchMatchesCode(possiblePart, code))
- {
- this.whereToSearch = genIndex;
- part = possiblePart;
- }
- }
- }
- }
- }
- return part;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_translateTextSpan
- // Purpose : translate the text span given the translation rules
- // Text spans may contain multiple pattern matches, we will translate all
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_translateTextSpan(code, offset)
- {
- var part = this.getParticipant(PTYPE_TEXT, code);
- if (part && part.length)
- {
- if (translatorInfo[this.index][part].patterns);
- {
- var arry = translatorInfo[this.index][part];
- for (var patternName in arry.patterns)
- {
- var pattern = arry.patterns[patternName];
- var isRE = arry.isPatternRE[patternName];
- if (isRE)
- {
- var paramNames = arry.paramNames[patternName];
- var paramArry;
- if (paramNames)
- paramArry = paramNames.split(",");
- else
- paramArry = Array();
- var re = pattern;
- re.lastIndex = 0;
- //re.compile();
- var matchesArry;
- while ((matchesArry = re.exec(code)) != null)
- {
- var params = new Array();
- for (var i = 1; i < matchesArry.length; i++)
- {
- if (paramArry && paramArry.length >= i && paramArry[i-1].length)
- {
- params[paramArry[i-1]] = matchesArry[i];
- }
- }
- this.params = params;
- var trans = this.getData(part, matchesArry[0]);
- var translate = true;
- if ((this.translatorClass == "MM_CFML") && ((trans.type == "dynamic data") || (trans.type == "dynamic image")))
- {
- translate = !this.CFOutput.IsEmpty();
- if (translate)
- {
- var queryName = this.CFOutput.Peek();
- if (queryName && queryName.length && trans.attributes.indexOf("SOURCE=\"\"") != -1)
- {
- trans.attributes = trans.attributes.replace(/SOURCE=""/g, "SOURCE=" + queryName);
- }
- }
- }
- if (translate)
- {
- this.translateText(matchesArry[0], offset + matchesArry.index, trans);
- }
- //if we use the exec while loop with a non-global pattern,
- // we will produce an infinite loop. exit the loop if not global.
- if (!re.global)
- {
- alert("INTERNAL ERROR: non-global search pattern in participant: " + part);
- break;
- }
- }
- }
- }
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_startMegaLock
- // Purpose : Signals the beginning of a mega lock, where several tags, tag spans,
- // and so forth should be translated and aggregated into a single locked region.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_startMegaLock(offset)
- {
- if (this.inMegaLock)
- return;
-
- if (debugMegaLock)
- alert("StartMegaLock(" + offset + ")");
- this.translator.previewMode(true);
- this.inMegaLock = true;
- this.megaLockPreCodeOffset = offset;
- this.megaLockCode = new QuickString();
- this.megaLockTranslation = new QuickString();
- this.megaLockSnapshot = new Snapshot(this.enclosingTags, offset);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_addToMegaLock
- // Purpose : Keeps megaLockCode and megaLockTranslation up to date
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_addToMegaLock(preCode, code, translation)
- {
- if (!this.inMegaLock)
- return;
-
- if (debugMegaLock)
- alert("AddToMegaLock\n" +
- "PreCode...\n" + preCode + "\n" +
- "Code...\n" + code + "\n" +
- "Translation...\n" + translation + "\n");
-
- // If this is the first translated item, we need to drop any leading
- // whitespace characters from the code and from the translation
- if (this.megaLockCode.isEmpty())
- {
- var preCodeLength = preCode.length;
- this.megaLockPreCodeOffset = this.megaLockSnapshot.offset - preCodeLength;
- this.megaLockCode.add(code);
- this.megaLockTranslation.add(translation.substr(preCodeLength));
- }
- // Otherwise, we want to include them.
- else
- {
- this.megaLockCode.add(preCode);
- this.megaLockCode.add(code);
- this.megaLockTranslation.add(translation);
- }
-
- if (debugMegaLock)
- alert("Code...\n" + this.megaLockCode.toString());
- if (debugMegaLock)
- alert("Translation...\n" + this.megaLockTranslation.toString());
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_finishMegaLock
- // Purpose : Signals the end of a mega lock
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_finishMegaLock(lockAttributes)
- {
- if (!this.inMegaLock)
- return;
-
- if (debugMegaLock)
- alert("FinishMegaLock\n" +
- "PreCodeOffset..." + this.megaLockPreCodeOffset + "\n" +
- "Offset..." + this.megaLockSnapshot.offset + "\n" +
- "Code...\n" + this.megaLockCode.toString() + "\n" +
- "Translation...\n" + this.megaLockTranslation.toString());
-
- this.translator.previewMode(false);
- this.translator.resetPosition(this.megaLockPreCodeOffset);
- var megaLockCodeString = this.megaLockCode.toString();
- var result = this.translator.translateText(megaLockCodeString, this.megaLockSnapshot.offset, "", "as is", "", "", "", this.megaLockTranslation.toString(), lockAttributes);
-
- var endOffset = this.megaLockSnapshot.offset + megaLockCodeString.length;
-
- if (this.inEditMode)
- {
- this.editModeFullTranslation.add(result);
- if (endOffset >= this.editModeEndOffset)
- {
- this.endEditMode();
- }
- }
-
- this.translator.resetPosition(endOffset);
- this.inMegaLock = false;
- this.megaLockCode = null;
- this.megaLockTranslation = null;
- return result;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_startEditMode
- // Purpose : Sets things up when we've finished parsing a control in normal mode and are ready for edit mode.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_startEditMode(endOffset, code, translation)
- {
- this.inEditMode = true;
- this.mode = "edit";
- this.editModeEndOffset = endOffset;
- this.editModeFullCode = code;
- this.editModeFullTranslation = new QuickString(translation);
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_endEditMode
- // Purpose : Wraps things up when we've finished parsing a control in normal mode and in edit mode
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_endEditMode()
- {
- var result = this.translator.translateTag("", this.editModeEndOffset, "", "as is", "", "", "", "<mm:toggleVisibility mode=end>", "");
- this.editModeFullTranslation.add(result);
-
- if (this.tagSpanCache)
- {
- this.tagSpanCache.setTranslation(this.editModeFullCode, this.editModeFullTranslation.toString());
- }
-
- this.inEditMode = false;
- this.mode = "preview";
- this.editModeEndOffset = -1;
- this.editModeFullCode = null;
- this.editModeFullTranslation = null;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_setDecoration
- // Purpose : sets decoration on or off. Should be off for sections of the document
- // that have been locked by the Live Data Translators.
- // Arguments: decoration - true for sections that have been locked by the Live Data translator
- // false otherwise.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_setDecoration(decoration)
- {
- this.translator.setDecoration(decoration);
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_restartParse
- // Purpose : restarts Parsing of document this gets called when we encounter a meta tag that is different
- // than the default encoding.
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_restartParse()
- {
- this.translator.restartParse();
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_pushOpenTag
- // Purpose : Updates this.enclosingTags with a new open tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_pushOpenTag(trailingFormat)
- {
- var tag = this.getCurrentTagName();
- tag = tag.toLowerCase();
-
- var isComplete = (trailingFormat.length > 0 &&
- trailingFormat[trailingFormat.length-1] == '/');
- if (!isComplete)
- {
- this.enclosingTags.push(tag);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : TM_popCloseTag
- // Purpose : Updates this.enclosingTags with a new close tag
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TM_popCloseTag()
- {
- var tag = this.getCurrentTagName();
- tag = tag.toLowerCase();
- var found = false;
- while (this.enclosingTags.length > 0 && !found)
- found = (this.enclosingTags.pop() == tag);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : Snapshot class to maintain information needed to reparse document
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function Snapshot(enclosingTags, offset)
- {
- this.enclosingTags = enclosingTags.concat();
- this.offset = offset;
- }
-
- function TM_takeSnapshot(offset)
- {
- return new Snapshot(this.enclosingTags, offset);
- }
-
- function TM_restoreSnapshot(snapshot)
- {
- this.translator.offsetAdj += snapshot.offset;
- this.translator.resetPosition(0);
- this.inStr = this.inStr.substr(snapshot.offset);
- this.megaLockPreCodeOffset -= snapshot.offset;
- this.editModeEndOffset -= snapshot.offset;
- this.enclosingTags = snapshot.enclosingTags;
- // Do these last, since snapshot may be the same as megaLockSnapshot or tagSpanSnapshot
- if (this.megaLockSnapshot)
- this.megaLockSnapshot.offset -= snapshot.offset;
- if (this.tagSpanSnapshot)
- this.tagSpanSnapshot.offset -= snapshot.offset;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Function : Stack Class to maintain cfOutput query names
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function Stack()
- {
- // Members
- this.data = new Array(50);
- this.tos = -1;
- Stack.prototype.Push = Stack_Push;
- Stack.prototype.Pop = Stack_Pop;
- Stack.prototype.Peek = Stack_Peek;
- Stack.prototype.IsEmpty = Stack_IsEmpty;
- }
-
- function Stack_Push(value)
- {
- if (this.tos < -1)
- {
- this.tos = -1;
- }
- this.tos += 1;
- this.data[this.tos] = value;
- }
-
- function Stack_Pop()
- {
- var top = null;
- if (this.tos >= 0)
- {
- top = this.data[this.tos];
- this.tos -= 1;
- }
-
- return top;
- }
-
- function Stack_Peek()
- {
- var top = null;
- if (this.tos >= 0)
- {
- top = this.data[this.tos];
- }
-
- return top;
- }
-
- function Stack_IsEmpty()
- {
- if (this.tos < 0)
- {
- return true;
- }
-
- return false;
- }
-